package com.example.onlinemonitoring.comCenter;

import com.alibaba.druid.sql.ast.statement.SQLIfStatement.Else;
import com.example.onlinemonitoring.Util.CRC16;
import com.example.onlinemonitoring.Util.CommPortManager;
import com.example.onlinemonitoring.Util.HexUtil;
import com.example.onlinemonitoring.model.O2andsf6sensor;
import com.example.onlinemonitoring.model.Sctmwlsensor;
import com.example.onlinemonitoring.model.common.MyResult;
import com.example.onlinemonitoring.model.O2andsf6history;
import com.example.onlinemonitoring.model.Appdevice;
import com.example.onlinemonitoring.serviceImpl.O2andsf6sensorServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.context.annotation.Scope;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;

/*
环境监控
*/
@Service("o2andsf6Com")
@Scope("prototype")
public class O2andsf6Com extends CommPortManager {
    @Autowired
    private O2andsf6sensorServiceImpl o2andsf6sensorServiceImpl;
    int cmd = 1;
    int SF6AllAlarmStatus = 0;
    int O2AllAlarmStatus = 0;
    int AllalarmLevel = 0;// 报警等级
    String AllalarmMessage = "";// 报警消息
    List<Integer> Allarray = new ArrayList<>();

    @Override
    public void receiveData(String str) {
        try {
            str = str.toUpperCase();
            setText(str);
            String addrstr = str.substring(0, 2);
            Integer addr = parseHex4(addrstr);

            if (!"03".equals(str.substring(2, 4)))
                return;
            int ckaddr = 0;
            reSend[addrindex] = 0;
            Integer startIndex = 3;// 数据起始位置
            setText("设备返回数据： 站点号：" + ad.getStationid() + " 设备组：" + ad.getDevicegroup() + " 设备地址：" + addr);
            int num = 0;
            O2andsf6sensor o2andsf6sensor = new O2andsf6sensor();
            o2andsf6sensor.setStationid(ad.getStationid());
            o2andsf6sensor.setDeviceaddr(addr);
            o2andsf6sensor.setDevicegroup(ad.getDevicegroup());
            MyResult<O2andsf6sensor> res = o2andsf6sensorServiceImpl.getList(o2andsf6sensor);

            if (cmd == 1) {
                if (str.length() != 266)
                    return;
                if (res.getCount() >= 16)
                    num = 16;
                else
                    num = res.getCount();
                for (int i = 0; i < num; i++) {
                    ckaddr = (i * 16);

                    O2andsf6sensor record = res.getData().get(i);
                    if (record == null) {
                        setText("当前数据库无监测点：设备地址" + addr + "的监测点" + i + 1 + " ！ 请先添加该监测点！");
                        return;
                    }

                    if (record.getInuse() == 0)
                        continue;
                    float SF6 = Integer.parseInt(str.substring(ckaddr + 6, ckaddr + 8), 16) * 256
                            + Integer.parseInt(str.substring(ckaddr + 8, ckaddr + 10), 16);
                    float O2Concn = Integer.parseInt(str.substring(ckaddr + 10, ckaddr + 12), 16) * 256
                            + Integer.parseInt(str.substring(ckaddr + 12, ckaddr + 14), 16);

                    float temperature = Integer.parseInt(str.substring(ckaddr + 14, ckaddr + 16), 16) * 256
                            + Integer.parseInt(str.substring(ckaddr + 16, ckaddr + 18), 16);
                    if (temperature == 0)
                        ;
                    else
                        temperature = temperature - 0x01F4;
                    float humidity = Integer.parseInt(str.substring(ckaddr + 18, ckaddr + 20), 16) * 256
                            + Integer.parseInt(str.substring(ckaddr + 20, ckaddr + 22), 16);
                    setText("温度：" + temperature / 10 + "℃ " + " 湿度: " + humidity + "% " + " SF6:" + SF6 + "% "
                            + " 氧气浓度：" + O2Concn / 10 + "%");
                    setText(" 监测点:" + (i + 1));

                    // String stlyestr = record.getStyle();
                    // if((stlyestr==null)||(stlyestr.equals("")))
                    // {
                    // stlyestr="temperature|1|温度,humidity|1|湿度,sf6|1|SF6,o2consistence|1|氧气浓度,";
                    // o2andsf6sensor.setStyle(stlyestr);
                    // }
                    if (O2Concn == 0)
                        continue;
                    o2andsf6sensor.setPointaddr(record.getPointaddr());
                    o2andsf6sensor.setLasttemperature(temperature / 10);
                    o2andsf6sensor.setLasthumidity(humidity);
                    o2andsf6sensor.setLastsf6(SF6);
                    o2andsf6sensor.setLasto2consistence(O2Concn / 10);
                    AddAndUpdate(record, o2andsf6sensor);
                }

                cmd = 1;
                if (res.getCount() >= 16)
                    cmd = 2;
                else
                    addrindex++;

            } else if (cmd == 2) {
                if (str.length() != 266)
                    return;
                for (int i = 16; i < res.getCount(); i++) {
                    ckaddr = ((i - 16) * 16);

                    O2andsf6sensor record = res.getData().get(i);

                    if (record.getInuse() == 0)
                        continue;

                    float SF6 = Integer.parseInt(str.substring(ckaddr + 6, ckaddr + 8), 16) * 256
                            + Integer.parseInt(str.substring(ckaddr + 8, ckaddr + 10), 16);
                    float O2Concn = Integer.parseInt(str.substring(ckaddr + 10, ckaddr + 12), 16) * 256
                            + Integer.parseInt(str.substring(ckaddr + 12, ckaddr + 14), 16);
                    float temperature = Integer.parseInt(str.substring(ckaddr + 14, ckaddr + 16), 16) * 256
                            + Integer.parseInt(str.substring(ckaddr + 16, ckaddr + 18), 16);
                    if (temperature == 0)
                        ;
                    else
                        temperature = temperature - 0x01F4;
                    float humidity = Integer.parseInt(str.substring(ckaddr + 18, ckaddr + 20), 16) * 256
                            + Integer.parseInt(str.substring(ckaddr + 20, ckaddr + 22), 16);
                    setText("温度：" + temperature / 10 + "℃ " + " 湿度:" + humidity + "% " + "SF6:" + SF6 + "% " + " 氧气浓度："
                            + O2Concn / 10 + "%");
                    setText(" 监测点:" + (i + 1));

                    // String stlyestr = record.getStyle();
                    // if(stlyestr==null)
                    // {
                    // stlyestr="temperature|1|温度,humidity|1|湿度,sf6|1|SF6,o2consistence|1|氧气浓度,";
                    // o2andsf6sensor.setStyle(stlyestr);
                    // }
                    if (O2Concn == 0)
                        continue;
                    o2andsf6sensor.setPointaddr(record.getPointaddr());
                    o2andsf6sensor.setLasttemperature(temperature / 10);
                    o2andsf6sensor.setLasthumidity(humidity);
                    o2andsf6sensor.setLastsf6(SF6);
                    o2andsf6sensor.setLasto2consistence(O2Concn / 10);
                    AddAndUpdate(record, o2andsf6sensor);
                }

                cmd = 1;
                addrindex++;
            }
            // else if(cmd==3)
            // {
            // if(str.length()==42)
            // {
            // SF6AllAlarmStatus = (Integer.parseInt(str.substring(ckaddr + 6, ckaddr + 8),
            // 16) + Integer.parseInt(str.substring(ckaddr + 8, ckaddr + 10), 16)) & 0x2;
            // int Fengjistatus = (Integer.parseInt(str.substring(ckaddr + 10, ckaddr + 12),
            // 16) + Integer.parseInt(str.substring(ckaddr + 12, ckaddr + 14), 16))&0x1;
            // O2AllAlarmStatus = (Integer.parseInt(str.substring(ckaddr + 14, ckaddr + 16),
            // 16) + Integer.parseInt(str.substring(ckaddr + 16, ckaddr + 18), 16)) & 0x2;

            // //Fengjistatus = 2;
            // for (int i = 0; i < res.getCount(); i++)
            // {

            // O2andsf6sensor record = res.getData().get(i);
            // if(record.getInuse()==0)
            // continue;

            // o2andsf6sensor.setPointaddr(record.getPointaddr());
            // // O2andsf6sensor record =
            // o2andsf6sensorServiceImpl.getModel(o2andsf6sensor);
            // // if (record == null) {
            // // //setText("当前数据库无监测点：设备地址" + addr + "的监测点" + i+16 + " ！ 请先添加该监测点！");
            // // continue;
            // // }

            // record.setFengjistatus(Fengjistatus);
            // if ( o2andsf6sensorServiceImpl.Update(record, false) == 0) {
            // setText("更新实时数据失败，请检查数据库连接");
            // }
            // }
            // // AllalarmLevel = 0;// 报警等级
            // // AllalarmMessage = "";// 报警消息
            // // Allarray.clear();
            // // Allarray.add(SF6AllAlarmStatus);
            // // Allarray.add(O2AllAlarmStatus);
            // //Allarray.add(record.getLastalarmlevel());
            // //AllalarmLevel = HexUtil.MAX(Allarray);
            // //record.setLastalarmlevel(alarmLevel);
            // // if (SF6AllAlarmStatus == 2)
            // // AllalarmMessage += "主机sf6总报警！ ";
            // // if (O2AllAlarmStatus == 2)
            // // AllalarmMessage += "主机氧气总报警！ ";
            // }
            // else{
            // setText("从设备返回的风机数据有误！请检查串口！");
            // }
            // cmd = 1;
            // addrindex++;
            // }
            // else if(cmd==4)
            // {
            // if(str.length()==18)
            // {

            // //for (int i = 1; i <= 32; i++)
            // {

            // // O2andsf6sensor o2andsf6sensor = new O2andsf6sensor();
            // // o2andsf6sensor.setStationid(ad.getStationid());
            // // o2andsf6sensor.setDevicegroup(ad.getDevicegroup());
            // // o2andsf6sensor.setDeviceaddr(addr);
            // // o2andsf6sensor.setPointaddr(i);
            // // O2andsf6sensor record =
            // o2andsf6sensorServiceImpl.getModel(o2andsf6sensor);
            // // if (record == null) {
            // // //setText("当前数据库无监测点：设备地址" + addr + "的监测点" + i+16 + " ！ 请先添加该监测点！");
            // // continue;
            // // }
            // // if(record.getInuse()==0)
            // // continue;
            // // int alarmLevel = 0;// 报警等级
            // // String alarmMessage = "";// 报警消息
            // // List<Integer> array = new ArrayList<>();
            // AllalarmLevel = 0;// 报警等级
            // AllalarmMessage = "";// 报警消息
            // Allarray.clear();
            // Allarray.add(SF6AllAlarmStatus);
            // Allarray.add(O2AllAlarmStatus);
            // //Allarray.add(record.getLastalarmlevel());
            // //AllalarmLevel = HexUtil.MAX(Allarray);
            // //record.setLastalarmlevel(alarmLevel);
            // if (SF6AllAlarmStatus == 2)
            // AllalarmMessage += "主机sf6总报警！ ";
            // if (O2AllAlarmStatus == 2)
            // AllalarmMessage += "主机氧气总报警！ ";
            // //AllalarmMessage += record.getLastalarmmessage();

            // // record.setLastalarmmessage(AllalarmMessage);
            // // record.setSf6allalarmstatus(SF6AllAlarmStatus);
            // // record.setO2allalarmstatus(O2AllAlarmStatus);
            // // if ( o2andsf6sensorServiceImpl.Update(record, false) == 0) {
            // // setText("更新实时数据失败，请检查数据库连接");
            // // }
            // }
            // }
            // else{
            // setText("从设备返回的报警数据有误！请检查串口！");
            // }
            // cmd = 1;
            // addrindex++;
            // }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    @Transactional
    private void AddAndUpdate(O2andsf6sensor record, O2andsf6sensor sensor) {
        int alarmLevel = 0;// 报警等级
        String alarmMessage = "";// 报警消息
        // 获取数据库中的报警值相关
        if (record.getTemperaturealarmvalue() == null ||
                record.getTemperaturealarmrelievevalue() == null ||
                record.getTemperaturewarnvalue() == null ||
                record.getTemperaturewarnrelievevalue() == null ||
                record.getHumidityalarmvalue() == null ||
                record.getHumidityalarmrelievevalue() == null ||
                record.getHumiditywarnvalue() == null ||
                record.getHumiditywarnrelievevalue() == null ||
                record.getSf6alarmvalue() == null ||
                record.getSf6alarmrelievevalue() == null ||
                record.getSf6warnvalue() == null ||
                record.getSf6warnrelievevalue() == null ||
                record.getO2alarmvalue() == null ||
                record.getO2alarmrelievevalue() == null ||
                record.getO2warnvalue() == null ||
                record.getO2warnrelievevalue() == null) {
            setText("设备地址" + record.getDeviceaddr() + "的监测点" + record.getPointaddr() + " 未设置报警值！");
            return;
        }
        List<Integer> array = new ArrayList<>();
        sensor.setLasttemperaturealarmstatus(
                GetAlarmStatus(isnull(sensor.getLasttemperature()), isnull(record.getTemperaturealarmvalue()),
                        isnull(record.getTemperaturealarmrelievevalue()), isnull(record.getTemperaturewarnvalue()),
                        isnull(record.getTemperaturewarnrelievevalue()),
                        isnull(record.getLasttemperaturealarmstatus()), true, record.getPointname() + "温度",
                        record.getDevicegroup(), record.getDeviceaddr(),
                        record.getPointname(), record.getPointaddr()));
        alarmMessage += GetAlarmMessage(sensor.getLasttemperaturealarmstatus(), "温度");
        array.add(sensor.getLasttemperaturealarmstatus());
        sensor.setLasthumidityalarmstatus(
                GetAlarmStatus(isnull(sensor.getLasthumidity()), isnull(record.getHumidityalarmvalue()),
                        isnull(record.getHumidityalarmrelievevalue()), isnull(record.getHumiditywarnvalue()),
                        isnull(record.getHumiditywarnrelievevalue()),
                        isnull(record.getLasthumidityalarmstatus()), true, record.getPointname() + "湿度",
                        record.getDevicegroup(), record.getDeviceaddr(),
                        record.getPointname(), record.getPointaddr()));
        alarmMessage += GetAlarmMessage(sensor.getLasthumidityalarmstatus(), "湿度");
        array.add(sensor.getLasthumidityalarmstatus());
        sensor.setLastsf6alarmstatus(
                GetAlarmStatus(isnull(sensor.getLastsf6()), isnull(record.getSf6alarmvalue()),
                        isnull(record.getSf6warnrelievevalue()), isnull(record.getSf6warnvalue()),
                        isnull(record.getSf6warnrelievevalue()),
                        isnull(record.getLastsf6alarmstatus()), true, record.getPointname() + "SF6",
                        record.getDevicegroup(), record.getDeviceaddr(),
                        record.getPointname(), record.getPointaddr()));
        alarmMessage += GetAlarmMessage(sensor.getLastsf6alarmstatus(), "SF6");
        array.add(sensor.getLastsf6alarmstatus());
        sensor.setLasto2alarmstatus(
                GetAlarmStatus(isnull(sensor.getLasto2consistence()), isnull(record.getO2alarmvalue()),
                        isnull(record.getO2alarmrelievevalue()), isnull(record.getO2warnvalue()),
                        isnull(record.getO2warnrelievevalue()),
                        isnull(record.getLasto2alarmstatus()), false, record.getPointname() + "氧气浓度",
                        record.getDevicegroup(), record.getDeviceaddr(),
                        record.getPointname(), record.getPointaddr()));
        alarmMessage += GetAlarmMessage(sensor.getLasto2alarmstatus(), "氧气浓度");
        array.add(sensor.getLasto2alarmstatus());

        // sensor.setSf6allalarmstatus(SF6AllAlarmStatus);
        // sensor.setO2allalarmstatus(O2AllAlarmStatus);
        alarmMessage += AllalarmMessage;
        // array.add(SF6AllAlarmStatus);
        // array.add(O2AllAlarmStatus);

        alarmLevel = HexUtil.MAX(array);
        sensor.setLastalarmlevel(alarmLevel);
        sensor.setLastalarmmessage(alarmMessage);
        sensor.setLastcommunicationstatus(0);
        sensor.setLastdatatime(new Date());
        sensor.setLasthisdatatime(addHistory(record));
        if (o2andsf6sensorServiceImpl.Update(sensor, false) == 0) {
            setText("更新实时数据失败，请检查数据库连接");
        }
    }

    private Date addHistory(O2andsf6sensor sensor) {
        if (sensor != null) {
            if (sensor.getLasthisdatatime() == null) {
                add(sensor);
                return new Date();
            } else {
                long lasttime = 0;
                long nowtime = 0;
                try {
                    lasttime = HexUtil.todate(sensor.getLasthisdatatime()).getTime();
                    nowtime = HexUtil.todate(new Date()).getTime();
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                int timersp = 60000;
                if (sensor.getLastalarmlevel() != 0) {
                    timersp = ad.getHisalarmtimersp() * 1000;
                } else {
                    timersp = ad.getHistimersp() * 1000;
                }
                if (lasttime + timersp < nowtime) {
                    add(sensor);
                    return new Date();
                }
            }
        }
        return null;
    }

    private void add(O2andsf6sensor sensor) {
        O2andsf6history his = new O2andsf6history();
        his.setDeviceaddr(sensor.getDeviceaddr());
        his.setDevicegroup(sensor.getDevicegroup());
        his.setAlarmlevel(sensor.getLastalarmlevel());
        his.setAlarmmessage(sensor.getLastalarmmessage());
        his.setDatatime(sensor.getLastdatatime());
        his.setPointname(sensor.getPointname());
        his.setStationid(sensor.getStationid());
        his.setCommunicationstatus(sensor.getLastcommunicationstatus());
        // 需要添加自己定义的属性
        his.setAddrname(sensor.getAddrname());
        his.setPointaddr(sensor.getPointaddr());
        his.setTemperature(sensor.getLasttemperature());
        his.setTemperaturealarmstatus(sensor.getLasttemperaturealarmstatus());
        his.setHumidity(sensor.getLasthumidity());
        his.setHumidityalarmstatus(sensor.getLasthumidityalarmstatus());
        his.setSf6(sensor.getLastsf6());
        his.setFengjistatus(sensor.getFengjistatus());
        his.setSf6alarmstatus(sensor.getLastsf6alarmstatus());
        his.setO2consistence(sensor.getLasto2consistence());
        his.setO2alarmstatus(sensor.getLasto2alarmstatus());
        his.setSf6allalarmstatus(sensor.getSf6allalarmstatus());
        his.setO2allalarmstatus(sensor.getO2allalarmstatus());
        o2andsf6sensorServiceImpl.Add(his);
    }

    @Async("threadPool")
    public void startSendThread(Appdevice Appdevice) throws Exception {
        checkType = "crc16";
        issend.put(Thread.currentThread().getId(), true);
        String cstr = "";
        String cmdtype = "";
        String nametype = "";

        int timersp = (int) Math.round(Appdevice.getTimersp() * 1000);
        while (issend.get(Thread.currentThread().getId()) != null) {
            if (isrun) {
                if (addrindex > Appdevice.getAddrmax() || addrindex < Appdevice.getAddrmin())
                    addrindex = Appdevice.getAddrmin();
                // cstr = String.format(Appdevice.getCmd(), String.format("%02X", addrindex));

                // if(cmd>2)
                // cmd=1;
                if (cmd == 1) {
                    cstr = String.format("%02X", addrindex) + "0310000040";
                } else if (cmd == 2) {
                    cstr = String.format("%02X", addrindex) + "0310400040";
                }
                // else if(cmd==3)
                // {
                // cstr = String.format("%02X", addrindex) + "0301000008";
                // }
                // else if(cmd==4)
                // {
                // cstr = String.format("%02X", addrindex) + "0301000002";
                // }
                cstr = cstr + CRC16.calcCrc16(cstr);
                Send(cstr);

                if (reSend[addrindex] > 3) {
                    o2andsf6sensorServiceImpl.UpdateStatus(ad, addrindex, 1);
                    reSend[addrindex] = 0;
                    addrindex++;
                }
                reSend[addrindex]++;
            } else if (rescode != 0) {
                setText(resmsg[rescode]);
            }
            Thread.sleep(timersp);
        }
    }

}
